package com.martin.ads.vrlib.filters.vr;

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.Matrix;

import com.martin.ads.vrlib.math.PositionOrientation;
import com.martin.ads.vrlib.object.Plane;
import com.martin.ads.vrlib.programs.GLPassThroughProgram;
import com.martin.ads.vrlib.textures.BitmapTexture;
import com.martin.ads.vrlib.utils.MatrixUtils;
import com.martin.ads.vrlib.utils.TextureUtils;

/**
 * Created by Ads on 2017/4/11.
 */

public class IconHotspot extends AbsHotspot {
    private BitmapTexture bitmapTexture;
    private String imagePath;
    private Bitmap bitmap;
    private GLPassThroughProgram glPassThroughProgram;

    private IconHotspot(Context context) {
        super(context);
        imagePlane = new Plane(false);
        bitmapTexture = new BitmapTexture();
        glPassThroughProgram = new GLPassThroughProgram(context);
    }

    @Override
    public void init() {
//        super.init();
        glPassThroughProgram.create();
        if (imagePath != null)
            bitmapTexture.loadWithAssetFile(context, imagePath);
        else bitmapTexture.loadBitmap(bitmap);
    }

    @Override
    public void onFilterChanged(int surfaceWidth, int surfaceHeight) {
        super.onFilterChanged(surfaceWidth, surfaceHeight);
        float screenRatio = (float) surfaceWidth / surfaceHeight;
        float videoRatio = (float) bitmapTexture.getImageWidth() / bitmapTexture.getImageHeight();
        int newWidth = bitmapTexture.getImageWidth();
        int newHeight = bitmapTexture.getImageHeight();
        if (videoRatio > screenRatio) {
            newWidth = bitmapTexture.getImageWidth();
            newHeight = (int) (bitmapTexture.getImageHeight() * videoRatio / screenRatio);
        } else {
            newWidth = (int) (bitmapTexture.getImageWidth() * screenRatio / videoRatio);
            newHeight = bitmapTexture.getImageHeight();
        }

        MatrixUtils.updateProjectionFit(bitmapTexture.getImageWidth(), bitmapTexture.getImageHeight(), surfaceWidth, surfaceHeight, hotspotOrthoProjectionMatrix);
        if (bitmapTexture.getImageWidth() < bitmapTexture.getImageHeight()) {
            MatrixUtils.updateProjectionFit(newWidth, newHeight, width, height, hotspotOrthoProjectionMatrix);
        }
    }

    @Override
    public void onDrawFrame(int textureId) {
        GLES20.glEnable(GLES20.GL_BLEND);
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
        glPassThroughProgram.use();
        TextureUtils.bindTexture2D(bitmapTexture.getImageTextureId(), GLES20.GL_TEXTURE1, glPassThroughProgram.getTextureSamplerHandle(), 1);
        imagePlane.uploadTexCoordinateBuffer(glPassThroughProgram.getTextureCoordinateHandle());
        imagePlane.uploadVerticesBuffer(glPassThroughProgram.getPositionHandle());
//        updateMatrix();
        positionOrientation.updateModelMatrix(hotSpotModelMatrix);
        Matrix.multiplyMM(resultMatrix, 0, hotSpotModelMatrix, 0, hotspotOrthoProjectionMatrix, 0);
        GLES20.glUniformMatrix4fv(glPassThroughProgram.getMVPMatrixHandle(), 1, false, resultMatrix, 0);
        imagePlane.draw();
        GLES20.glDisable(GLES20.GL_BLEND);
    }

    @Override
    public void destroy() {
        glPassThroughProgram.onDestroy();
    }

    public IconHotspot setPositionOrientation(PositionOrientation positionOrientation) {
        this.positionOrientation = positionOrientation;
        return this;
    }

    /**
     * if you have set imagePath, the bitmap will not be used.
     *
     * @param imagePath
     * @return
     */
    public IconHotspot setImagePath(String imagePath) {
        this.imagePath = imagePath;
        return this;
    }

    public IconHotspot setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
        return this;
    }

    public IconHotspot setAssumedScreenSize(float assumedScreenWidth, float assumedScreenHeight) {
        this.assumedScreenWidth = assumedScreenWidth;
        this.assumedScreenHeight = assumedScreenHeight;
        return this;
    }

    private int width;

    public IconHotspot width(int width) {
        this.width = width;
        return this;
    }

    private int height;

    public IconHotspot height(int height) {
        this.height = height;
        return this;
    }

    public static IconHotspot with(Context context) {
        return new IconHotspot(context);
    }
}
